/*
 * network.c
 * Michael du Breuil
 */

#include "common.h"
#include "net_local.h"
#include "cam_fetch.h"
#include "ftp_put.h"
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

//declared in network.h
pthread_mutex_t net_mutex;
pthread_cond_t   net_cond;

static int serverSocketFD, newsockfd;
static int clients[MAX_CLIENTS];


int net_init() {
  int portno;
  struct sockaddr_in serv_addr;
  serverSocketFD = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); //nonblocking, otherwise need a many threaded solution
  if (serverSocketFD < 0) {
     perror("ERROR: net_init() unable to open socket");
     exit(1);
  }
  memset(&serv_addr, 0, sizeof(serv_addr));
  portno = NET_PORT;
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);
  if (bind(serverSocketFD, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
    perror("ERROR: net_init unable to bind");
    exit(1);
  }

  for(int i = 0; i < MAX_CLIENTS; i++) {
    clients[i] = -1;
  }
  return 0;
}

void net_shutdown() {
  close(serverSocketFD);
  return;
}

/*
 * net_accept()
 * accepts any clients that are awaiting for connection
 */
void net_accept() {
  int i = 0;
  socklen_t clilen;
  struct sockaddr_in cli_addr;

  listen(serverSocketFD,5);
  clilen = sizeof(cli_addr);
  newsockfd = accept(serverSocketFD, (struct sockaddr *) &cli_addr, &clilen);
  if (newsockfd >= 0) {
    for(i = 0; i < MAX_CLIENTS; i++) {
      if(clients[i] < 0)
        break;
    }
    if(i < MAX_CLIENTS) {
      pthread_mutex_lock(&net_mutex);
      clients[i] = newsockfd;
      pthread_mutex_unlock(&net_mutex);
      printf("accepted a client\n");
    }
    else {
      printf("ERROR: net_run() no avalible client slots, dropping new connection\n");
      close(newsockfd);
    }
  }

  return;
}

/*
 * net_process()
 * processes any commands that a client has submitted
 */
void net_process() {
  message_t msg;
  int n = 0;

  for(int i = 0; i < MAX_CLIENTS; i++) {
    if(clients[i] < 0)
      continue;

    memset(&msg, 0, sizeof(msg));
    n = read(clients[i], &msg, sizeof(msg));
    if(n < 0)  //nothing was sent from this client so check the next
      continue;
printf("MSG: %s\n", (char *)msg.payload.cam_settings.url);
    switch(msg.type) {
      case MSG_STATUS:
        break;
      case MSG_CAM_SETTINGS:
        pthread_mutex_lock(&cam_mutex);
        memcpy(&cam_settings, &msg.payload, sizeof(cam_settings_t));
        pthread_cond_broadcast(&cam_cond);
        pthread_mutex_unlock(&cam_mutex);
        break;
      case MSG_FILE_SETTINGS:
        pthread_mutex_lock(&ftp_mutex);
        memcpy(&ftp_settings, &msg.payload, sizeof(ftp_settings_t));
        pthread_cond_broadcast(&ftp_cond);
        pthread_mutex_unlock(&ftp_mutex);
        break;
      default:
        break;
    }
  }
}
